/*
 * GeneticAlgorithm.h
 *
 *  Created on: Jan 16, 2012
 *      Author: luiz
 */

#ifndef GENETICALGORITHM_H_
#define GENETICALGORITHM_H_

#include <vector>
#include <string>
#include <map>

#include "../Entity/Instance.h"
#include "../Entity/Individual.h"
#include "../Entity/Layer.h"

class Simulation;

#include "../Entity/Simulation.h"
/*
 * Class implements Genetic Algorithm
 */


class GeneticAlgorithm
{
    Instance *instance_;

    int population_size_;

    int iterations_;

    std::vector<Individual> population_;

    double mutation_tax_;
    double crossover_tax_;
    int population_mutation_size_;
    int population_crossover_size_;
    int population_reproduction_size_;
    int population_random_size_;

    Layer *layer_default_;

    Simulation *simulation_;


    /*
     * Evaluate all populate individuals
     */
    void evaluate_population();

    void save_individuals(const std::vector<Individual> &individuals,const std::string base_name="");

    void save_individuals(const std::map<int,Individual> &individuals,const std::string base_name="");

    void save_individual(const Individual & individual,const std::string &file_name="");

    void save_statistics_individuals(std::map<int,Individual> individuals);

public:

    GeneticAlgorithm(Instance *instance,int population_size, int iterations);

    virtual ~GeneticAlgorithm();

    virtual void execute();

    std::string print_population_fitness();

    std::vector<int> selection_roulette_selector_population_index(int number_of_individual_selected,int window);

    std::vector<int> selection_reward_based_selection_population_index(int number_of_individual_selected);

    std::vector<Individual> execute_mutation(std::vector<int> index_individual_list);

    std::vector<Individual> execute_crossover(std::vector<int> index_individual_list);

    void save_statistics(std::vector<Samples> &statistics,const std::map<int,Individual> &individuals= std::map<int,Individual>()) ;

    std::vector<Individual> execute_reproduction();

    /*
     * GET AND SET
     */

    void set_mutation_tax(double tax);

    void set_crossover_tax(double tax);

    void set_population_crossover_size(int size);

    void set_population_mutation_size(int size);

    void set_population_reproduction_size(int size);

    void set_population_random_size(int size);

    double mutation_tax();

    double crossover_tax();

    int population_mutation_size();

    int population_crossover_size();

    int population_reproduction_size();

    int population_random_size();

    void set_layer_default(Layer*layer);

    Layer* layer_default();

    Simulation* simulation();

    void set_simulation(Simulation *simulation);

    void clear_execution();

};



#endif /* GENETICALGORITHM_H_ */

